package com.bjbn.controller;

import com.bjbn.dto.*;
import com.bjbn.service.Webapi4IotService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * WebAPI控制器
 *
 * @author bjbn
 */
@RestController
@RequestMapping("/CAN/IOT/internetOfThings/V1")
@Tag(name = "物联网平台WebAPI接口", description = "物联网平台WebAPI相关接口")
public class IotController {

    @Autowired
    private Webapi4IotService webapiService;

    /**
     * 3.1.1 查询数据上报内容
     *
     * @param request 查询请求
     * @return 响应结果
     */
    @PostMapping("/data/getDatas")
    @Operation(summary = "查询数据上报内容", description = "查询数据上报列表，当需要查询某设备上报数据列表时，传入产品ID、设备ID、查询起止时间、分页参数，返回设备的查询时间段内上报的数据列表")
    public Mono<ResponseEntity<Map<String, Object>>> getIotData(@RequestBody IotDataRequest request) {
        return webapiService.getIotData(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.2 发送指令
     *
     * @param request 指令请求
     * @return 响应结果
     */
    @PostMapping("/command/sendCommand")
    @Operation(summary = "发送指令", description = "支持物模型、透传、脚本解析数据类型的产品设备进行单设备指令下发，包含直连设备（mqtt、tcp、lwm2m和coap），网关设备，网关子设备，云云对接设备和泛协议设备")
    public Mono<ResponseEntity<Map<String, Object>>> sendIotCommand(@RequestBody IotCommandRequest request) {
        return webapiService.sendIotCommand(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.3 群组指令下发
     *
     * @param request 群组指令请求
     * @return 响应结果
     */
    @PostMapping("/command/sendGroupCommand")
    @Operation(summary = "群组指令下发", description = "支持物模型、透传、脚本解析数据类型的产品设备进行分组指令下发，包含直连设备（mqtt、tcp、lwm2m），网关设备，网关子设备，和泛协议设备")
    public Mono<ResponseEntity<Map<String, Object>>> sendGroupCommand(@RequestBody IotGroupCommandRequest request) {
        return webapiService.sendGroupCommand(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.4 取消指令
     *
     * @param request 取消指令请求
     * @return 响应结果
     */
    @PostMapping("/command/cancelCommand")
    @Operation(summary = "取消指令", description = "支持Mqtt、Tcp、ModbusRtu、ModbusTcp、Lwm2m、Coap协议产品，取消已下发给设备的状态是‘已保存’的指令")
    public Mono<ResponseEntity<Map<String, Object>>> cancelCommand(@RequestBody IotCancelCommandRequest request) {
        return webapiService.cancelCommand(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.5 查询指令下发列表
     *
     * @param request 查询指令列表请求
     * @return 响应结果
     */
    @PostMapping("/command/getCommands")
    @Operation(summary = "查询指令下发列表", description = "支持查询单设备下发的指令列表。当需要查询某设备下发的指令列表时，传入设备ID、产品ID、指令状态、查询起止时间和分页参数，返回时间段内的指令日志列表")
    public Mono<ResponseEntity<Map<String, Object>>> getCommands(@RequestBody IotCommandListRequest request) {
        return webapiService.getCommands(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.6 查询指令详情
     *
     * @param request 查询指令详情请求
     * @return 响应结果
     */
    @PostMapping("/command/getCommand")
    @Operation(summary = "查询指令详情", description = "当需要查询某设备下发的某个指令详情时，传入设备ID、指令ID，返回该指令的详情")
    public Mono<ResponseEntity<Map<String, Object>>> getCommand(@RequestBody IotCommandDetailRequest request) {
        return webapiService.getCommand(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.7 分页查询设备列表
     *
     * @param request 查询设备列表请求
     * @return 响应结果
     */
    @PostMapping("/device/device/list")
    @Operation(summary = "分页查询设备列表", description = "查询设备列表清单")
    public Mono<ResponseEntity<Map<String, Object>>> getDeviceList(@RequestBody IotDeviceListRequest request) {
        return webapiService.getDeviceList(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.8 查询设备详细信息
     *
     * @param request 查询设备详情请求
     * @return 响应结果
     */
    @PostMapping("/device/device/detail")
    @Operation(summary = "查询设备详细信息", description = "查询设备详细信息")
    public Mono<ResponseEntity<Map<String, Object>>> getDeviceDetail(@RequestBody IotDeviceDetailRequest request) {
        return webapiService.getDeviceDetail(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.9 设备档案查询
     *
     * @param request 设备档案查询请求
     * @return 响应结果
     */
    @PostMapping("/device_archives_mgr/getArchives")
    @Operation(summary = "设备档案查询", description = "设备档案查询")
    public Mono<ResponseEntity<Map<String, Object>>> getDeviceArchives(@RequestBody IotDeviceArchivesRequest request) {
        return webapiService.getDeviceArchives(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.10 查询产品信息
     *
     * @param request 查询产品信息
     * @return 响应结果
     */
    @PostMapping("/product/detail")
    @Operation(summary = "查询产品信息", description = "查询产品信息")
    public Mono<ResponseEntity<Map<String, Object>>> productDetail(@RequestBody IotProductDetailRequest request) {
        return webapiService.getIotProductDetail(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

    /**
     * 3.1.11 分页查询产品信息列表
     *
     * @param request 查询产品信息
     * @return 响应结果
     */
    @PostMapping("/product/v1/list")
    @Operation(summary = "分页查询产品信息列表", description = "分页查询产品信息列表")
    public Mono<ResponseEntity<Map<String, Object>>> productList(@RequestBody IotProductListRequest request) {
        return webapiService.getIotProductList(request)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.noContent().build());
    }

}